package dao;

import java.util.Date;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import utils.DateUtils;
import utils.XmlUtils;
import dominio.ItemRemitoTransporte;
import dominio.OrdenPedido;
import dominio.ReferenciaRemitoTransporte;
import dominio.RemitoTransporte;
import dominio.Rodamiento;

public class RemitoTransporteXmlDAO {
	private static RemitoTransporteXmlDAO instance;

	public static RemitoTransporteXmlDAO getInstance() {
		if (instance == null)
			instance = new RemitoTransporteXmlDAO();
		return instance;
	}

	private RemitoTransporteXmlDAO() {}

	public RemitoTransporte parse(Document xml) throws Exception {
		// Remito
		Element elementRemito = XmlUtils.getElement(xml, "Remito");
		if (elementRemito != null) {
			RemitoTransporte remito = new RemitoTransporte();
			// Fecha
			Date fecha = DateUtils.parse(elementRemito.getAttribute("fecha"));
			remito.setFecha(fecha);
			// Referencia
			Element elementReferencia = XmlUtils.getElement(elementRemito, "Referencia");
			if (elementReferencia != null) {
				NodeList ordenesPedido = elementReferencia.getElementsByTagName("OrdenPedido");
				for (int i = 0; i < ordenesPedido.getLength(); ++i)
					remito.agregarReferencia(parseReferencia((Element) ordenesPedido.item(i)));
				return remito;
			}
		}
		throw new Exception("Formato incorrecto del archivo XML.");
	}

	private ReferenciaRemitoTransporte parseReferencia(Element elementOrden) throws Exception {
		ReferenciaRemitoTransporte referencia = new ReferenciaRemitoTransporte();
		// OrdenPedido
		OrdenPedido orden = new OrdenPedido();
		orden.setId(Integer.parseInt(elementOrden.getAttribute("numero")));
		referencia.setOrdenPedido(orden);
		// Rodamientos
		Element elementRodamientos = XmlUtils.getElement(elementOrden, "Rodamientos");
		if (elementRodamientos == null)
			throw new Exception("Formato incorrecto del archivo XML.");
		NodeList items = elementRodamientos.getElementsByTagName("Item");
		for (int i = 0; i < items.getLength(); ++i) {
			Element elementItem = (Element) items.item(i);
			ItemRemitoTransporte item = parseItem(elementItem);
			referencia.agregarItem(item);
		}
		return referencia;
	}

	private ItemRemitoTransporte parseItem(Element item) throws Exception {
		// Serie
		String serie = item.getAttribute("serie");
		// Sufijo
		Element elementSufijo = XmlUtils.getElement(item, "Sufijo");
		// Marca
		Element elementMarca = XmlUtils.getElement(item, "Marca");
		// Pais
		Element elementPais = XmlUtils.getElement(item, "Origen");
		// Cantidad
		Element elementCantidad = XmlUtils.getElement(item, "Cantidad");
		if (serie != null && elementSufijo != null && elementMarca != null && elementPais != null && elementCantidad != null) {
			ItemRemitoTransporte i = new ItemRemitoTransporte();
			// Rodamiento
			Rodamiento r = new Rodamiento();
			r.setSerie(serie);
			r.setSufijo(elementSufijo.getTextContent());
			r.setMarca(elementMarca.getTextContent());
			r.setPais(elementPais.getTextContent());
			i.setRodamiento(r);
			// Cantidad
			i.setCantidad(Integer.parseInt(elementCantidad.getTextContent()));
			return i;
		}
		throw new Exception("Formato incorrecto del archivo XML.");
	}

	public Document create(RemitoTransporte remito) {
		Document xml = XmlFactory.getInstance().newDocument();
		// Remito
		Element elementRemito = xml.createElement("Remito");
		elementRemito.setAttribute("numero", Integer.toString(remito.getId()));
		xml.appendChild(elementRemito);
		// Fecha
		elementRemito.setAttribute("fecha", DateUtils.format(remito.getFecha()));
		// Referencia
		Element elementReferencia = xml.createElement("Referencia");
		elementRemito.appendChild(elementReferencia);
		for (ReferenciaRemitoTransporte referencia : remito.getReferencias()) {
			// OrdenPedido
			Element elementPedido = xml.createElement("OrdenPedido");
			elementPedido.setAttribute("numero", Integer.toString(referencia.getOrdenPedido().getId()));
			elementReferencia.appendChild(elementPedido);
			// Rodamientos
			Element elementRodamientos = xml.createElement("Rodamientos");
			elementPedido.appendChild(elementRodamientos);
			for (ItemRemitoTransporte i : referencia.getItems()) {
				Rodamiento r = i.getRodamiento();
				// Item
				Element elementItem = xml.createElement("Item");
				elementItem.setAttribute("serie", r.getSerie());
				// Sufijo
				Element elementSufijo = xml.createElement("Sufijo");
				elementSufijo.setTextContent(r.getSufijo());
				elementItem.appendChild(elementSufijo);
				// Marca
				Element elementMarca = xml.createElement("Marca");
				elementMarca.setTextContent(r.getMarca());
				elementItem.appendChild(elementMarca);
				// Origen
				Element elementOrigen = xml.createElement("Origen");
				elementOrigen.setTextContent(r.getPais());
				elementItem.appendChild(elementOrigen);
				// Cantidad
				Element elementCantidad = xml.createElement("Cantidad");
				elementCantidad.setTextContent(Integer.toString(i.getCantidad()));
				elementItem.appendChild(elementCantidad);
				elementRodamientos.appendChild(elementItem);
			}
		}
		return xml;
	}
}